package server

import (
	"data_service/models"
	"errors"
	"fmt"
	"time"
)

// PointsService 提供积分相关业务逻辑
// 供 handler 层调用，解耦 handler 与 models
// 只负责业务流程，不直接操作数据库
type PointsService struct{}

func NewPointsService() *PointsService {
	return &PointsService{}
}

// DailyCheckInResult 每日签到结果
type DailyCheckInResult struct {
	Message      string `json:"message"`
	PointsAwarded int    `json:"points_awarded"`
	TotalPoints   int    `json:"total_points"`
	IsFirstLogin  bool   `json:"is_first_login"`
}

// PointsHistory 积分历史记录
type PointsHistory struct {
	ID          uint      `json:"id"`
	UserID      int       `json:"user_id"`
	Points      int       `json:"points"`
	Description string    `json:"description"`
	CreatedAt   time.Time `json:"created_at"`
}

// UserRank 用户排行榜
type UserRank struct {
	UserID   int    `json:"user_id"`
	UserName string `json:"user_name"`
	Points   int    `json:"points"`
	Level    int    `json:"level"`
}

// DailyCheckIn 用户每日签到
func (s *PointsService) DailyCheckIn(userID int) (*DailyCheckInResult, error) {
	// 获取用户信息
	user, err := s.GetUserByID(fmt.Sprintf("%d", userID))
	if err != nil {
		return nil, errors.New("用户不存在")
	}

	// 检查今天是否已经签到
	today := time.Now().Format("2006-01-02")
	var pointsHistory models.PointsHistory
	err = models.GetDB().Where("user_id = ? AND description LIKE ? AND created_at >= ?", userID, "%每日签到%", today+" 00:00:00").First(&pointsHistory).Error
	
	// 如果今天已经签到，返回提示
	if err == nil {
		return &DailyCheckInResult{
			Message:      "今天已经签到过了",
			PointsAwarded: 0,
			TotalPoints:   user.Points,
			IsFirstLogin:  false,
		}, nil
	}

	// 计算签到奖励积分（首次登录额外奖励）
	isFirstLogin := user.LastLogin.IsZero()
	awardPoints := 10 // 默认签到奖励
	
	if isFirstLogin {
		awardPoints = 50 // 首次登录奖励
	}

	// 更新用户积分和最后登录时间
	user.Points += awardPoints
	user.LastLogin = time.Now()
	
	// 更新用户信息
	if err := models.GetDB().Save(user).Error; err != nil {
		return nil, errors.New("更新用户积分失败")
	}

	// 记录积分历史
	history := models.PointsHistory{
		UserID:      userID,
		Points:      awardPoints,
		Description: fmt.Sprintf("每日签到奖励%s", map[bool]string{true: "(首次登录)"}[isFirstLogin]),
	}
	if err := models.GetDB().Create(&history).Error; err != nil {
		// 这里不返回错误，因为积分已经更新成功
		fmt.Printf("记录积分历史失败: %v\n", err)
	}

	return &DailyCheckInResult{
		Message:      map[bool]string{true: "首次登录奖励", false: "签到成功"}[isFirstLogin],
		PointsAwarded: awardPoints,
		TotalPoints:   user.Points,
		IsFirstLogin:  isFirstLogin,
	}, nil
}

// AddPointsForPostResult 发布动态奖励积分结果
type AddPointsForPostResult struct {
	Message      string `json:"message"`
	PointsAwarded int    `json:"points_awarded"`
	TotalPoints   int    `json:"total_points"`
}

// AddPointsForPost 发布动态奖励积分
func (s *PointsService) AddPointsForPost(userID int) (*AddPointsForPostResult, error) {
	// 获取用户信息
	user, err := s.GetUserByID(fmt.Sprintf("%d", userID))
	if err != nil {
		return nil, errors.New("用户不存在")
	}

	// 奖励积分
	awardPoints := 5
	user.Points += awardPoints

	// 更新用户信息
	if err := models.GetDB().Save(user).Error; err != nil {
		return nil, errors.New("更新用户积分失败")
	}

	// 记录积分历史
	history := models.PointsHistory{
		UserID:      userID,
		Points:      awardPoints,
		Description: "发布动态奖励",
	}
	if err := models.GetDB().Create(&history).Error; err != nil {
		// 这里不返回错误，因为积分已经更新成功
		fmt.Printf("记录积分历史失败: %v\n", err)
	}

	return &AddPointsForPostResult{
		Message:      "发布动态奖励积分成功",
		PointsAwarded: awardPoints,
		TotalPoints:   user.Points,
	}, nil
}

// GetPointsHistory 获取积分历史记录
func (s *PointsService) GetPointsHistory(userID int) ([]PointsHistory, error) {
	var histories []PointsHistory
	
	// 查询积分历史记录
	err := models.GetDB().Table("points_histories").Where("user_id = ?", userID).Order("created_at DESC").Find(&histories).Error
	if err != nil {
		return nil, errors.New("获取积分历史记录失败")
	}

	return histories, nil
}

// GetPointsRanking 获取积分排行榜
func (s *PointsService) GetPointsRanking() ([]UserRank, error) {
	var ranking []UserRank

	// 添加调试信息
	fmt.Printf("=== 积分排行榜查询调试 ===\n")
	
	// 先查询所有用户，看看积分情况
	var allUsers []models.User
	err := models.GetDB().Select("id, name, points, level, status").Find(&allUsers).Error
	if err != nil {
		fmt.Printf("查询所有用户失败: %v\n", err)
	} else {
		fmt.Printf("所有用户数量: %d\n", len(allUsers))
		for i, user := range allUsers {
			if i < 10 { // 只显示前10个用户
				fmt.Printf("用户 %d: ID=%d, Name=%s, Points=%d, Level=%d, Status=%s\n", 
					i+1, user.ID, user.Name, user.Points, user.Level, user.Status)
			}
		}
	}

	// 查询积分排行榜（只显示有积分的用户，前100名）
	err = models.GetDB().Table("users").Select("id as user_id, name as user_name, points, level").Where("status = ? AND points > 0", "active").Order("points DESC").Limit(100).Find(&ranking).Error
	if err != nil {
		fmt.Printf("查询积分排行榜失败: %v\n", err)
		return nil, errors.New("获取积分排行榜失败")
	}

	fmt.Printf("积分排行榜结果数量: %d\n", len(ranking))
	for i, rank := range ranking {
		if i < 5 { // 只显示前5个结果
			fmt.Printf("排行榜 %d: UserID=%d, UserName=%s, Points=%d, Level=%d\n", 
				i+1, rank.UserID, rank.UserName, rank.Points, rank.Level)
		}
	}
	fmt.Printf("========================\n")

	return ranking, nil
}

// GetUserByID 获取用户信息
func (s *PointsService) GetUserByID(id string) (*models.User, error) {
	var user models.User
	if err := models.GetDB().Where("id = ?", id).First(&user).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

// ValidateUserToken 验证用户Token
func (s *PointsService) ValidateUserToken(userId string, token string) bool {
	return models.ValidateUserToken(userId, token)
}